[转]cocos2d-x 2x 菜鸟编塔防 01 准备工作

点击打开链接

一.前言

最近在学习2dx,看了几个源码,手很是痒痒,下面跟我一下编写一个类似保卫大萝卜的塔防游戏吧。


二.不废话开始编代码。

我用的cocos2d-x 的版本是2.04 ,编辑器是vs2010.首先创建一个工程,我们取名字叫“TDgame”。
之后我们添加几个常用到的模块。
1.动画管理器,AnimationManager类
AnimationManager类这是个单例的类,大家要问这样弄个单例类出来有什么好处呢,有什么作用呢,一开始我也是不明白,最后看了看魔塔的源代码,总结了一下:1. 实现了一体化,也就是说把所有的动画加载都放到一个函数中,我们可以让这个函数出现在想要的位置上,比如,我们有一大堆的精灵动画,如果在游戏中加载起来会让游戏有点卡,这时候我们就可以创建一个进入游戏时的加载页面,同时执行加载动画。一般游戏也都是这么做的。

  1. 规范代码,有利于编写代码。

好了它的优点和作用就说到这吧,肯定还有很多,我也就不知道了。

关于单例的问题大家可以看看这篇文章
http://www.zilongshanren.com/cocos2d-x-design-pattern-singleton1/

回到主题,首先我们粘贴一段代码。


第一步:复制黏贴

在魔塔的源代码中有一个单例类的模板,无脑的复制黏贴,这个模板是动画管理器AnimationManager的基类,这个有什么用呢,其实用处很简单就是一个单例的模板让继承他的子类都变成单例模式,下次再做别的游戏时用到直接继承,多方便。当然你也可以不用这个模板,直接让AnimationManager变成单例类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#ifndef _SINGLETON_H
#define _SINGLETON_H
template <class T>
class Singleton
{
public:
//获取类的唯一实例
static inline T* instance();
//释放类的唯一实例
void release();
protected:
Singleton(void){}
~Singleton(void){}
static T* _instance;
};
template <class T>
inline T* Singleton<T>::instance()
{
if(!_instance)
_instance = new T;
return _instance;
}
template <class T>
void Singleton<T>::release()
{
if (!_instance)
return;
delete _instance;
_instance = 0;
}
//cpp文件中需要先声明静态变量
#define DECLARE_SINGLETON_MEMBER(_Ty) \
template <> _Ty* Singleton<_Ty>::_instance = NULL;
#endif//_SINGLETON_H

好了这样我们的标准的单例基类就写好了,记住这是一个.h文件 注意:
1.子类要在子类的cpp文件开始写上DECLARE_SINGLETON_MEMBER(子类的名字)
2.子类最好写上构造和析构函数


第二步:编写动画管理器AnimationManager类

先看代码:###AnimationManager.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#ifndef _ANIMATION_MANAGER_H_
#define _ANIMATION_MANAGER_H_
#include "cocos2d.h"
#include "Singleton.h"
#include "type.h"
using namespace cocos2d;
class AnimationManager : public Singleton<AnimationManager>
{
public:
AnimationManager();
~AnimationManager();
//初始化动画模版缓存表
bool initAnimationMap();
//根据名字得到一个动画模板
CCAnimation* getAnimation(int key);
//创建一个动画实例
CCAnimate* createAnimate(int key);
//创建一个动画实例
CCAnimate* createAnimate(const char* key);
//清空所有缓存
void releaseAllCacha();
protected:
//加载勇士行走动画模版
CCAnimation* createAnimationByDirection(HeroDirection direction);
};
//定义动画管理器实例的别名
#define sAnimationMgr AnimationManager::instance()
#endif

AnimationManager.cpp

#include "AnimationManager.h" 
DECLARE_SINGLETON_MEMBER(AnimationManager); 



AnimationManager::AnimationManager() 
{ 

} 

AnimationManager::~AnimationManager() 
{ 

} 

bool AnimationManager::initAnimationMap() 
{ 
    bool sRet = false; 
    do  
    { 
        //1.添加图片进内存 
        CCTexture2D * creepTexture = CCTextureCache::sharedTextureCache()->addImage("boy.png"); 
        CC_BREAK_IF(!creepTexture); 
        //2.加载各个方向的敌人动画 
        char temp[20]; 
        sprintf(temp, "%d", aDown); 
        //加载勇士向下走的动画 
        CCAnimationCache::sharedAnimationCache()->addAnimation(createAnimationByDirection(kDown), temp); 
        sprintf(temp, "%d", aRight); 
        //加载勇士向右走的动画 
        CCAnimationCache::sharedAnimationCache()->addAnimation(createAnimationByDirection(kRight), temp); 
        sprintf(temp, "%d", aLeft); 
        //加载勇士向左走的动画 
        CCAnimationCache::sharedAnimationCache()->addAnimation(createAnimationByDirection(kLeft), temp); 
        sprintf(temp, "%d", aUp); 
        //加载勇士向上走的动画 
        CCAnimationCache::sharedAnimationCache()->addAnimation(createAnimationByDirection(kUp), temp); 

        sRet = true; 
    } while (0); 
    return sRet; 
} 

CCAnimation* AnimationManager::getAnimation( int key ) 
{ 
    char temp[20]; 
    sprintf(temp, "%d", key); 
    return CCAnimationCache::sharedAnimationCache()->animationByName(temp); 
} 

CCAnimate* AnimationManager::createAnimate( int key ) 
{ 
    //获取指定动画模版 
    CCAnimation* anim = getAnimation(key); 
    if(anim) 
    { 
        //根据动画模版生成一个动画实例 
    //  return cocos2d::CCAnimate::actionWithAnimation(anim); 
        return cocos2d::CCAnimate::create(anim); 
    } 
    return NULL; 
} 

CCAnimate* AnimationManager::createAnimate( const char* key ) 
{ 
    //获取指定动画模版 
    CCAnimation* anim = CCAnimationCache::sharedAnimationCache()->animationByName(key); 
    if(anim) 
    { 
        //根据动画模版生成一个动画实例 
        return cocos2d::CCAnimate::create(anim); 
    } 
    return NULL; 
} 

CCAnimation* AnimationManager::createAnimationByDirection( HeroDirection direction ) 
{ 
    //3.生产剪切动画 
    CCTexture2D * creepTexture=CCTextureCache::sharedTextureCache()->textureForKey("boy.png"); 
    CCSpriteFrame *frame0, *frame1, *frame2, *frame3; 
    frame0 = CCSpriteFrame::createWithTexture(creepTexture, cocos2d::CCRectMake(47*0, 95*direction, 47, 95)); 
    frame1 = CCSpriteFrame::createWithTexture(creepTexture, cocos2d::CCRectMake(47*1, 95*direction, 47, 95)); 
    frame2 = CCSpriteFrame::createWithTexture(creepTexture, cocos2d::CCRectMake(47*2, 95*direction, 47, 95)); 
    frame3 = CCSpriteFrame::createWithTexture(creepTexture, cocos2d::CCRectMake(47*3, 95*direction, 47, 95)); 
    CCArray * animFrames = new CCArray(4); 
    animFrames->addObject(frame0); 
    animFrames->addObject(frame1); 
    animFrames->addObject(frame2); 
    animFrames->addObject(frame3); 
    CC_SAFE_RETAIN(animFrames); 
    CCAnimation * animation= CCAnimation::createWithSpriteFrames(animFrames,0.5f); 

    animFrames->release(); 
    return animation; 
} 

void AnimationManager::releaseAllCacha() 
{ 

}

建立完这个动画管理单例后,用法也是很简单,只需要调用那几个getXXXX 就行,当然这个动画管理器功能还比较简单,因为我是个新手所以不能一下吧所有的功能都写上,还是先用到哪些写那些。


第三步:全局数据

之后我们在建立一个单例类,来保存一些全局数据
HWorld.h

#ifndef __HWORLD_H__ 
#define __HWORLD_H__ 

#include "cocos2d.h" 
#include "type.h" 
#include "Singleton.h" 
using namespace cocos2d; 
class HWorld: 
    public Singleton<HWorld> 
{ 
public: 
    HWorld(); 
    ~HWorld(); 
    //初始化 
    bool initHWorld(); 
    //清空所有缓存 
    void releaseAll(); 
public: 
    //路点数组 
    CCPointArray * _wayPoint;    
}; 
//定义动画管理器实例的别名 
#define sHWorld HWorld::instance() 
#endif

HWorld.cpp

#include "HWorld.h"  
DECLARE_SINGLETON_MEMBER(HWorld);  

bool HWorld::initHWorld()  
{  
    return true;  
}  

void HWorld::releaseAll()  
{  
}  

HWorld::HWorld()  
{  
}  

HWorld::~HWorld()  
{  
}

目前这个类里面之后一个路点的数组,这个数组中保存了地图上需要转弯地方的坐标,其他的东西以后再添加。
当然还有我们的枚举,把它放在一个.h文件中,方便查看
type.h

#ifndef __TYPE_H__  
#define __TYPE_H__  

typedef enum {  
    kDown =  0,//向下方向  
    kLeft = 1,//向左方向  
    kRight= 2,//向右方向  
    kUp = 3,//向上方向  
    kNormal,  
} HeroDirection;//勇士方向  


typedef enum 
{  
    aDown = 0,//向下行走动画  
    aLeft,//向左行走动画  
    aRight,//向右行走动画  
    aUp,//向上行走动画  
    aFight,//刀光动画  
} AnimationKey;//动画模版键值  
//定义怪物的类型  
typedef enum 
{  
    kHighBlood=0,//高血量怪物  
    kQuick = 1,  

}CreepType;  
//----------------定义一个creep中所用到的tag--------  
typedef enum 
{  
    kSprite =0,//精灵的标签  
    kSpeedAction = 1,//控制速度的action所用的标签  
    kFoveverAction = 2,//控制精灵帧的action标签  
}CreepTag;  
 enum   
{  
    kZMap = 0,//地图的zOrder  
    kZNPC,  
    kZTeleport,  
    kZHero,//勇士精灵的zOrder  
    kZTip,//提示信息的zOrder  
};//GameLayer中各部分的显示zOrder及tag  
#endif

好了,生成一下。

Jerky Lu wechat
欢迎加入微信公众号